Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encrypt bearer tokens at rest #302

Merged
merged 1 commit into from
Aug 2, 2023
Merged

encrypt bearer tokens at rest #302

merged 1 commit into from
Aug 2, 2023

Conversation

jbr
Copy link
Contributor

@jbr jbr commented Jul 14, 2023

closes #215

@jbr jbr requested a review from a team as a code owner July 14, 2023 23:46
src/crypter.rs Fixed Show fixed Hide fixed
src/crypter.rs Fixed Show fixed Hide fixed
@jbr jbr force-pushed the crypter branch 7 times, most recently from d05023f to ad5e7ba Compare July 17, 2023 16:41
src/crypter.rs Outdated
let mut keys = s
.split(',')
.map(|s| {
STANDARD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to use NO_PAD? (base64 padding is only necessary/useful if multiple b64 values need to be concatenated together, then parsed apart again; I don't think we need to do that.)

Less important, but any reason not to use the URL-safe alphabet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no opinion on this. I feel like this comes up every time we base64 something. I'm happy to switch it to URL_SAFE_NO_PAD or whatever is easiest for the generating side. Humans should never see these values so it doesn't matter how they're encoded

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Padding is not sufficient to allow concatenation of multiple base64-encoded values together. As a counterexample, note that AAAA is a valid encoding of three null bytes in all of base64, base64url, base64 without padding, and base64url without padding. Thus, it is not possible to unambiguously decode multiple concatenated encoded values from an input that consists of A repeated a multiple of four times.

RFC 4648 section 3.2 is very brief, but it seems to suggest that this is instead useful when the protocol employing base64 may be unclear about the "end of file".

Weighing in the other direction, base64 with padding is both recommended by RFC 4648 and better supported by tooling.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 2a40071fb31f6d98bef09fe22b3fecc403f36025

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, the padding argument came from here, but the counterexample is clear. This makes it even less clear what the purpose of base64 padding is...

src/crypter.rs Show resolved Hide resolved
src/crypter.rs Outdated Show resolved Hide resolved
src/crypter.rs Show resolved Hide resolved
src/crypter.rs Outdated Show resolved Hide resolved
@jbr
Copy link
Contributor Author

jbr commented Jul 17, 2023

The sort of review I'm primarily looking for on this PR: Is my use of aes-gcm cryptographically correct/safe? Is it valid to concatenate the nonce and cipher text in a different order than Janus does? Is my implementation of rotation correct or is there a way of saving something about the key in the ciphertext so we can select the right key before trying to decrypt?

@divergentdave
Copy link
Contributor

Regarding key rotation: I think trial decryption is fine for our purposes for now, as we expect the number of keys will be around one to three, and the ciphertext will not be large. (for bearer tokens, it'll be a few dozen bytes, for other highly sensitive secrets, it'll likely be similar)

There is prior art for specifying which key to use, but there's not much to it, just adding another fixed-length prefix before the nonce. DAP does this with the 8-bit HpkeConfigId field in the HpkeCiphertext struct, and Google's Tink library does this with a 32-bit key ID at the start of most of its (non-compatibility oriented) ciphertext formats. Such a feature is mainly relevant for large ciphertexts, which make trial decryption expensive, but with this use case, I don't think we need to reinvent that particular wheel.

Copy link
Contributor

@tgeoghegan tgeoghegan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm inclined to agree with Bran's points about Crypter vs. Key but I don't think it's critical to fix that.

README.md Outdated Show resolved Hide resolved
@jbr jbr merged commit 7b1aeb0 into main Aug 2, 2023
6 checks passed
@jbr jbr deleted the crypter branch August 2, 2023 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

encrypt aggregator bearer tokens at rest
4 participants